﻿Imports System.Collections.Generic

Public Class RTData

#Region "构造函数"

    Sub New()
        ReDim _bufByte(MAXLENGTH - 1)
        ReDim _bufShort(MAXLENGTH - 1)
        ReDim _bufSingle(MAXLENGTH - 1)
    End Sub

    ''' <summary>
    ''' 测试用
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetTestValue() As Single
        If Me._index >= 225 Then
            Return _bufSingle(_index - 225)
        End If
    End Function


    Public Sub New(ByVal values() As Byte, ByVal rtd As RTDValueInfo, ByVal dtStart As DateTime, ByVal dtCurrent As DateTime)
        Dim i As Integer

        Dim sd As Integer
        sd = GetTimeDiff(dtStart, dtCurrent)

        If sd = 0 Then
            '第一条曲线加载1小时的数据
            For i = 0 To values.Length - 1
                _bufByte(i) = values(i)
            Next
        Else
            '不是第一条曲线，加载时间于先前加载曲线的开始日期同步
            For i = 0 To sd
                _bufByte(i) = values(360 - sd + i)
            Next
        End If

        For j As Integer = i To _bufByte.Length - 1
            _bufByte(j) = 0
        Next

        _rtdItem = rtd
        _startTime = dtStart
    End Sub

    Public Sub New(ByVal values() As Short, ByVal rtd As RTDValueInfo, ByVal dtStart As DateTime, ByVal dtCurrent As DateTime)
        Dim i As Integer

        Dim sd As Integer
        sd = GetTimeDiff(dtStart, dtCurrent)

        If sd = 0 Then
            '第一条曲线加载1小时的数据
            For i = 0 To values.Length - 1
                _bufShort(i) = values(i)
            Next
        Else
            '不是第一条曲线，加载时间于先前加载曲线的开始日期同步
            For i = 0 To sd
                _bufShort(i) = values(360 - sd + i)
            Next
        End If

        For j As Integer = i To _bufShort.Length - 1
            _bufShort(j) = 0
        Next


        _rtdItem = rtd
        _startTime = dtStart
    End Sub

    Public Sub New(ByVal values() As Single, ByVal rtd As RTDValueInfo, ByVal dtStart As DateTime, ByVal dtCurrent As DateTime)
        Dim i As Integer

        Dim sd As Integer
        sd = GetTimeDiff(dtStart, dtCurrent) Mod 100

        If sd = 0 Then
            '第一条曲线加载1小时的数据
            For i = 0 To values.Length - 1
                _bufSingle(i) = values(i)
            Next
        Else
            '不是第一条曲线，加载时间于先前加载曲线的开始日期同步
            For i = 0 To sd
                _bufSingle(i) = values(360 - sd + i)
            Next
        End If

        For j As Integer = i To _bufSingle.Length - 1
            _bufSingle(j) = 0
        Next

        Me._index = sd - 1

        _rtdItem = rtd
        _startTime = dtStart
    End Sub

    Public Sub New(ByVal values() As Byte, ByVal rtd As RTDValueInfo, ByVal index As Integer)
        MyClass.New()

        Dim i As Integer

        Dim sd As Integer
        'sd = GetTimeDiff(dtStart, dtCurrent)
        sd = index

        If sd = 0 Then
            '第一条曲线加载1小时的数据
            For i = 0 To values.Length - 1
                _bufByte(i) = values(i)
            Next
        Else
            '不是第一条曲线，加载时间于先前加载曲线的开始日期同步
            If sd < OneHourLength Then
                For i = 0 To sd
                    _bufByte(i) = values(OneHourLength - sd + i)
                Next
            Else
                For i = 0 To 360
                    _bufByte(sd - OneHourLength + i) = values(i)
                Next
            End If

        End If

        For j As Integer = i To _bufByte.Length - 1
            _bufByte(j) = 0
        Next

        Me._index = sd
        _rtdItem = rtd
        '_startTime = dtStart
    End Sub

    Public Sub New(ByVal values() As Byte, ByVal rtd As RTDValueInfo, ByVal index As Integer, ByVal NextIndex As Integer)
        MyClass.New()


        Dim i As Integer

        Dim sd As Integer
        'sd = GetTimeDiff(dtStart, dtCurrent)
        sd = Math.Min(_bufByte.Length, values.Length)

        ReDim _bufByte(sd - 1)

        If index = 0 Then
            '第一条曲线加载1小时的数据
            For i = 0 To sd - 1
                _bufByte(i) = values(i)
            Next
        Else
            '不是第一条曲线，加载时间于先前加载曲线的开始日期同步
            If sd < OneHourLength Then
                For i = 0 To sd
                    _bufByte(i) = values(OneHourLength - sd + i)
                Next
            Else
                For i = 0 To 360
                    _bufByte(sd - OneHourLength + i) = values(i)
                Next
            End If

        End If

        For j As Integer = i To _bufByte.Length - 1
            _bufByte(j) = 0
        Next

        Me._index = sd - 1
        _rtdItem = rtd
        '_startTime = dtStart
    End Sub

    Public Sub New(ByVal values() As Short, ByVal rtd As RTDValueInfo, ByVal index As Integer)
        MyClass.New()

        Dim i As Integer

        Dim sd As Integer
        'sd = GetTimeDiff(dtStart, dtCurrent)
        sd = index

        If sd = 0 Then
            '第一条曲线加载1小时的数据
            For i = 0 To values.Length - 1
                _bufShort(i) = values(i)
            Next
        Else
            '不是第一条曲线，加载时间于先前加载曲线的开始日期同步
            If sd < OneHourLength Then
                For i = 0 To sd
                    _bufShort(i) = values(OneHourLength - sd + i)
                Next
            Else
                For i = 0 To 360
                    _bufShort(sd - OneHourLength + i) = values(i)
                Next
            End If

        End If

        For j As Integer = i To _bufShort.Length - 1
            _bufShort(j) = 0
        Next

        Me._index = sd
        _rtdItem = rtd
        '_startTime = dtStart
    End Sub

    Public Sub New(ByVal values() As Single, ByVal rtd As RTDValueInfo, ByVal index As Integer)
        MyClass.New()

        Dim i As Integer

        Dim sd As Integer
        'sd = GetTimeDiff(dtStart, dtCurrent) Mod 100
        sd = index

        If sd = 0 Then
            '第一条曲线加载1小时的数据
            For i = 0 To values.Length - 1
                _bufSingle(i) = values(i)
            Next
        Else
            '不是第一条曲线，加载时间与先前加载曲线的开始日期同步
            If sd < OneHourLength Then
                For i = 0 To sd
                    _bufSingle(i) = values(OneHourLength - sd + i)
                Next
            Else
                For i = 0 To sd - OneHourLength
                    _bufSingle(i) = Single.NaN
                Next

                For i = 0 To 360 - 1
                    _bufSingle(sd - (OneHourLength - 1) + i) = values(i)
                Next

            End If

        End If

        'For j As Integer = i To _bufSingle.Length - 1
        '    _bufSingle(j) = Single.NaN
        'Next

        Me._index = sd - 1

        _rtdItem = rtd
        '_startTime = dtStart
    End Sub


    Public Sub New(ByVal values() As Single, ByVal rtd As RTDValueInfo, ByVal index As Integer, ByVal nextIndex As Integer)
        MyClass.New()

        Dim i As Integer

        Dim sd As Integer
        'sd = GetTimeDiff(dtStart, dtCurrent) Mod 100

        sd = Math.Min(_bufByte.Length, values.Length)
        ReDim _bufByte(sd - 1)

        If index = 0 Then
            '第一条曲线加载1小时的数据
            For i = 0 To values.Length - 1
                _bufSingle(i) = values(i)
            Next
        Else
            '不是第一条曲线，加载时间与先前加载曲线的开始日期同步
            If sd < OneHourLength Then
                For i = 0 To sd
                    _bufSingle(i) = values(OneHourLength - sd + i)
                Next
            Else
                For i = 0 To 360
                    _bufSingle(sd - OneHourLength + i) = values(i)
                Next
            End If

        End If

        For j As Integer = i To _bufSingle.Length - 1
            _bufSingle(j) = 0
        Next

        Me._index = nextIndex - 1

        _rtdItem = rtd
        '_startTime = dtStart
    End Sub



    ''' <summary>
    ''' 返回2个时间之间的记录数据的次数（10秒一次）
    ''' </summary>
    ''' <param name="dtStart"></param>
    ''' <param name="dtEnd"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function GetTimeDiff(ByVal dtStart As DateTime, ByVal dtEnd As DateTime) As Integer
        Return DateDiff(DateInterval.Second, dtStart, dtEnd) '\ 10
    End Function

#End Region

    Const INTERVALSECOND As Integer = 10    '2次实时数据之间的间隔时间(秒)
    Const OneHourLength As Integer = 60 * (60 / INTERVALSECOND) '1小时的数据量
    Const MAXLENGTH As Integer = 75 * (60 / INTERVALSECOND) '最多保存最近2小时/75分钟的数据
    Const MAXGAP As Integer = 10 * (60 / INTERVALSECOND)       '至少保留最近1小时的实时数据

    Public _bufByte(MAXLENGTH - 1) As Byte
    Public _bufShort(MAXLENGTH - 1) As Short
    Public _bufSingle(MAXLENGTH - 1) As Single

    Private _index As Integer = 50

    Private _rtdItem As RTDValueInfo
    Public Property rtdItem() As RTDValueInfo
        Get
            Return _rtdItem
        End Get
        Set(ByVal value As RTDValueInfo)
            _rtdItem = value
        End Set
    End Property

    Private _startTime As DateTime
    Public Property startTime() As DateTime
        Get
            Return _startTime
        End Get
        Set(ByVal value As DateTime)
            _startTime = value
        End Set
    End Property

    ''' <summary>
    ''' 添加数据
    ''' </summary>
    ''' <param name="value"></param>
    ''' <remarks></remarks>
    Public Sub Add(ByVal value As Byte)
        If _index = MAXLENGTH - 1 Then
            DealArrayByte()
            _index = MAXLENGTH - MAXGAP
        Else
            _index += 1
        End If
        _bufByte(_index) = value
    End Sub

    Public Sub Add(ByVal value As Short)
        If _index = MAXLENGTH - 1 Then
            DealArrayShort()
            _index = MAXLENGTH - MAXGAP
        Else
            _index += 1
        End If
        _bufShort(_index) = value
    End Sub

    Public Sub Add(ByVal value As Single)
        If _index = MAXLENGTH - 1 Then
            DealArraySingle()
            _index = MAXLENGTH - MAXGAP
        Else
            _index += 1
        End If
        _bufSingle(_index) = value
    End Sub

    ''' <summary>
    ''' 数组向前移MAXGAP个数据
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub DealArrayByte()
        For i As Integer = 0 To MAXLENGTH - MAXGAP - 1
            _bufByte(i) = _bufByte(i + MAXGAP)
        Next
    End Sub

    Private Sub DealArrayShort()
        For i As Integer = 0 To MAXLENGTH - MAXGAP - 1
            _bufShort(i) = _bufShort(i + MAXGAP)
        Next
    End Sub

    Private Sub DealArraySingle()
        For i As Integer = 0 To MAXLENGTH - MAXGAP - 1
            _bufSingle(i) = _bufSingle(i + MAXGAP)
        Next
    End Sub

    Public ReadOnly Property CurrentIndex() As Integer
        Get
            Return _index
        End Get
    End Property

    Public ReadOnly Property Gap() As Integer
        Get
            Return MAXGAP
        End Get
    End Property

    Public ReadOnly Property Length() As Integer
        Get
            Return MAXLENGTH
        End Get
    End Property

    Protected Overrides Sub Finalize()
        MyBase.Finalize()
    End Sub
End Class

Public Interface IRTData
    Sub Add(ByVal value As Object)
    ReadOnly Property Length() As Integer
    ReadOnly Property CurrentIndex() As Integer
    ReadOnly Property Gap() As Integer
End Interface

 

